package com.example.OnlineStorage.Controller.ShareFiles;

import com.example.OnlineStorage.enums.GlobalVariables_String;
import com.example.OnlineStorage.pojo.Response.ApiResponse;
import com.example.OnlineStorage.service.ShareFiles.ShareFilesService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Tag(name = "共享文件操作API")
@RestController("ShareFiles")
@RequestMapping("/ShareFiles")
public class ShareFilesController {
    private final ShareFilesService shareFilesService;

    public ShareFilesController(ShareFilesService shareFilesService) {
        this.shareFilesService = shareFilesService;
    }

    // 用户令牌的全局变量
    private final String TOKEN = GlobalVariables_String.TOKEN.getValue();


    @Operation(summary = "在共享文件夹里面创建文件夹",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "从哪个路径创建", required = true),
            @Parameter(name = "name", description = "文件夹名称", required = true),
    })
    @PostMapping("/createDirectory")
    public ResponseEntity<Object> createDirectory(Long shareFileId,
                                                  String fromPath,
                                                  String name,
                                                  HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.createDirectory(shareFileId, fromPath, name, UUID))
                .build();
    }

    @Operation(summary = "创建共享文件夹",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "name", description = "文件夹名称", required = true),
    })

    @PostMapping("/createShareFile")
    public ResponseEntity<Object> createShare(String name,
                                              HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.createShareFiles(name, UUID))
                .build();
    }


    @Operation(summary = "上传文件之前进行一次查询服务器是否有了该文件",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "从哪个路径上传", required = true),
            @Parameter(name = "name", description = "文件名称", required = true),
            @Parameter(name = "intactSHA256", description = "完整文件的SHA256值", required = true),
            @Parameter(name = "AllChunkSHA256", description = "所有文件块的SHA256值", required = true),
    })
    @PostMapping("/isExist")
    public ResponseEntity<Object> isExist(Long shareFileId, String fromPath,
                                          String name,
                                          String intactSHA256,
                                          String[] AllChunkSHA256,
                                          HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.isExist(shareFileId, fromPath, name, intactSHA256, Arrays.asList(AllChunkSHA256), UUID))
                .build();
    }

    @Operation(summary = "上传文件分块",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "从哪个路径上传", required = true),
            @Parameter(name = "name", description = "文件名称", required = true),
            @Parameter(name = "intactSHA256", description = "完整文件的SHA256值", required = true),
            @Parameter(name = "ChunkSHA256", description = "文件块的SHA256值", required = true),
            @Parameter(name = "AllChunkSHA256", description = "所有文件块的SHA256值", required = true),
            @Parameter(name = "ChunkFile", description = "文件块", required = true),
    })
    @PostMapping("/putChunk")
    public ResponseEntity<Object> putChunk(Long shareFileId, String fromPath,
                                           String name,
                                           String intactSHA256,
                                           String ChunkSHA256,
                                           String[] AllChunkSHA256,
                                           MultipartFile ChunkFile,
                                           HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.putChunk(shareFileId, fromPath, name, intactSHA256, ChunkSHA256, Arrays.asList(AllChunkSHA256), ChunkFile, UUID))
                .build();
    }

    @Operation(summary = "修改文件夹、文件的名称",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "要修改的路径", required = true),
            @Parameter(name = "newName", description = "新名称", required = true),

    })
    @PostMapping("/reviseName")
    public ResponseEntity<Object> reviseName(Long shareFileId, String fromPath,
                                             String newName,
                                             HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.reviseName(shareFileId, fromPath, newName, UUID))
                .build();
    }

    @Operation(summary = "删除节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "要删除的路径", required = true),
    })
    @PostMapping("/deleteNode")
    public ResponseEntity<Object> deleteNode(Long shareFileId, String fromPath,
                                             HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.deleteNode(shareFileId, fromPath, UUID))
                .build();
    }

    @Operation(summary = "删除多个文件节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "要删除的路径列表", required = true),
            @Parameter(name = "token", description = "令牌", required = true, in = ParameterIn.HEADER)
    })
    @PostMapping("/deleteNodes")
    public ResponseEntity<Object> deleteNodes(Long shareFileId, String[] fromPath,
                                              HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.deleteNodes(shareFileId, Arrays.asList(fromPath), UUID))
                .build();
    }

    @Operation(summary = "恢复一个文件节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "要恢复的到的路径(只能是文件夹)", required = true),
            @Parameter(name = "cacheName", description = "缓存名称", required = true),
    })
    @PostMapping("/recoveryNode")
    public ResponseEntity<Object> recoveryNode(Long shareFileId, String fromPath,
                                               String cacheName,
                                               HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.recoveryNode(shareFileId, fromPath, cacheName, UUID))
                .build();
    }

    @Operation(summary = "获取共享文件夹回收站列表",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @GetMapping("/getCacheName")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
    })
    public ResponseEntity<Object> getCacheName(Long shareFileId, HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(shareFilesService.getCacheList(shareFileId, UUID))
                .build();
    }


    @Operation(summary = "移动节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "shareFileId", description = "共享文件夹id", required = true),
            @Parameter(name = "fromPath", description = "要移动的路径", required = true),
            @Parameter(name = "toPath", description = "要移动到的路径(只能是文件夹)", required = true),
            @Parameter(name = "token", description = "令牌", required = true, in = ParameterIn.HEADER)
    })
    @PostMapping("/moveNode")
    public ResponseEntity<Object> moveNode(Long shareFileId, String fromPath, String toPath, HttpServletRequest request) {
        String file = shareFilesService.moveNode(shareFileId, fromPath, toPath, request.getHeader(TOKEN));
        return ApiResponse.GetApiResponse().ok().body(file).build();
    }

    @Operation(summary = "添加共享空间")
    @Parameters({
            @Parameter(name = "userId", description = "共享用户源的id", required = true),
            @Parameter(name = "shareFileId", description = "共享用户源", required = true),
            @Parameter(name = "permission", description = "权限", required = true),
            @Parameter(name = "token", description = "令牌", required = true, in = ParameterIn.HEADER)
    })
    @PostMapping("/addShareFile")
    public ResponseEntity<Object> addShareFile(Long userId, Long shareFileId, Long permission, HttpServletRequest request) {
        shareFilesService.addShareFile(userId, shareFileId, permission, request.getHeader(TOKEN));
        return ApiResponse.GetApiResponse().ok().build();
    }
}
